'''
importer.py

Copyright 2009 Xavier Mendez Navarro aka Javi

This file is part of pysqlin

pysqlin is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 2 of the License.

pysqlin is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with pysqlin; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
'''
from framework.queries import Database
from framework.sqlinjection import SQLInjection
from framework.myhttp import InjectionData
from framework.baseclass import BPlugin
from framework.facade import Facade

import logging

class Importer(BPlugin):
    def __init__(self, api):
	BPlugin.__init__(self, api)

	self.__logger = logging.getLogger('lib.importer')

    def parameters(self): 
	return dict(
	    setstring = (True, 'If true sets error string automatically.')
	)

    def dbpstrike_to_dbpysqlin(self, db):
	return {
	    "MySQL": Database.MYSQL,
	    "MS Sql Server": Database.MSSQL,
	    "Oracle": Database.ORACLE,
	    "DB2": Database.DB2,
	    "PostgreSQL": Database.PSQL,
	    "Informix": Database.INFORMIX,
	    "Sybase": Database.SYBASE,
	    "MSAccess": Database.MSACCESS,
	    "Pointbase": Database.POINTBASE,
	}.get(db, None)

    def choose(self, all_sqli):
	if len(all_sqli) == 1:
	    return all_sqli[0]
	elif len(all_sqli) > 1:
	    n = 0
	    for url, post_data, cookie, var, method, itype, db, db_error in all_sqli:
		self.print_msg("%d.- %s [%s/%s/%s]" % (n, url, var, method, db))
		n = n + 1

	    self.print_msg("Choose injection number: ")
	    number = raw_input()

	    try:
		return all_sqli[int(number)]
	    except ValueError:
		self.print_error("You have to introduce a number")
	    except IndexError:
		self.print_error("You have to introduce a valid number")
	else:
	    self.print_error("No injections found!")

	return None

    def sqlimport_all(self, all_sqli):
	self.sqlimport(all_sqli[0], False)
	for raw_elem in all_sqli[1:]:
	    self.sqlimport(raw_elem)

    def sqlimport(self, raw_elem, new_session = True):
	if raw_elem is None: return


	url, post_data, cookie, var, method, itype, db, dberror = raw_elem

	if (db == 'None' or not db) and \
	   (dberror == 'None' or not dberror):
		self.print_error("Database not fingerprinted, nothing to import.")
		return
	elif (db == 'None' or not db) and dberror != 'None' and dberror:
	    db = dberror

	if new_session: Facade().new_session()
	data = self.get_session_data()
	self.print_status("Creating new session with sqli: %s [%s/%s/%s]" % (url, var, method, db))
	idata = InjectionData.from_raw(url, post_data, cookie, "", "", "", "", db)

	if idata is not None: data.update(idata)
	data.update_from_rawsqli(db, var, method, itype)

	if data['setstring']:
	    sqli = SQLInjection.from_error_string(data)

	    if sqli.injection_data[InjectionData.ERROR_MODE] != InjectionData.ERROR_MODE_POSITIVE and \
		sqli.injection_data[InjectionData.ERROR_MODE] != InjectionData.ERROR_MODE_NEGATIVE:

		self.print_error('Error string not found! Injection not usable yet. Hint: Have you set a correct session cookie?')
		return

	    self.print_status('Error string found automatically.')
	    data[InjectionData.ERROR_STRING] = sqli.injection_data[InjectionData.ERROR_STRING]
	    data[InjectionData.ERROR_MODE] = sqli.injection_data[InjectionData.ERROR_MODE]
